package cn.com.ejiakanghu.web;

import cn.com.ejiakanghu.annotation.LoginUser;
import cn.com.ejiakanghu.config.UrlConfig;
import cn.com.ejiakanghu.core.exceptions.BizException;
import cn.com.ejiakanghu.core.utils.RespUtil;
import cn.com.ejiakanghu.core.vo.BaseResult;
import cn.com.ejiakanghu.dto.OpenCityInfo;
import cn.com.ejiakanghu.form.HourReachHospitalForm;
import cn.com.ejiakanghu.service.UploadService;
import cn.com.ejiakanghu.vo.HourReachHospitalVo;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.linlinjava.litemall.core.util.HttpUtil;
import org.linlinjava.litemall.core.util.JacksonUtil;
import org.linlinjava.litemall.db.domain.AgedmallHospitalSend;
import org.linlinjava.litemall.db.domain.EjiaOpenCitys;
import org.linlinjava.litemall.db.domain.LitemallAddress;
import org.linlinjava.litemall.db.service.AgedmallHospitalSendService;
import org.linlinjava.litemall.db.service.EjiaOpenCityService;
import org.linlinjava.litemall.db.service.LitemallAddressService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.spring.web.json.Json;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

import static cn.com.ejiakanghu.config.UrlConfig.SEARCH_AROUND_LOCATION_URL;

/**
 * @author houzb
 * @Description
 * @create 2021-03-29 21:14
 */
@RestController
@RequestMapping("/common")
public class CommonController {
    private Logger logger = LoggerFactory.getLogger(CommonController.class);
    @Value("${litemall.filePath}")
    private String FILEPATH;
    @Value("${litemall.fileUrl}")
    private String FILEURL;
    @Autowired
    private EjiaOpenCityService ejiaOpenCityService;
    @Autowired
    private LitemallAddressService addressService;
    @Autowired
    private AgedmallHospitalSendService agedmallHospitalSendService;
    @Resource
    private UploadService uploadService;



    /***
     * @api {get} /common/areaList 获取行政列表
     * @apiGroup 常用接口
     * @apiVersion 0.1.0
     * @apiDescription 获取当前的省市县行政区域列表
     * @apiSuccess {Object} Object 省市县区域列表
     * @apiSuccessExample {json} Success-Response:
              {"code":0,"msg":"", "data":{ "list": {}, "total":11,"page":1,"limit":30,"pages":1 }}
     */
    @RequestMapping("/areaList")
    public BaseResult getAllAdministrativeList(){
        //TODO
        return RespUtil.success();
    }

    /**
     * @api {get} /common/openCity 获取开通城市
     * @apiGroup 常用接口
     * @apiVersion 0.1.0
     * @apiDescription 获取已开通的城市列表
     * @apiSuccess {int} code 请求状态码，0表示成功,其它参考状态码文档
     * @apiSuccess {String} message 结果消息说明
     * @apiSuccess {boolean} success 请求是否成功
     * @apiSuccess {Object} data 请求响应的数据
     * @apiSuccessExample {json} Success-Response:
     * {
     *     "code": "请求状态码，0表示成功，其它参考状态码文档",
     *     "success": "请求是否成功",
     *     "timestamp": "服务器当前时间戳10位精确到秒",
     *     "message": "请求成功/失败说明",
     *     "data": {
     *         "citys": [{
     *             "cityName": "城市名称"
     *         }]
     *     }
     * }
     */
    @RequestMapping("/openCity")
    public Object getOpenCityList() {
        List<EjiaOpenCitys> citysList = ejiaOpenCityService.getList();
        List<OpenCityInfo> openCityInfoList = new ArrayList<>();
        citysList.stream().forEach(c->{
            openCityInfoList.add(new OpenCityInfo(c.getCity()));
        });
        Map<String,Object> data = new HashMap<>();
        data.put("citys", openCityInfoList);
        return RespUtil.success(data);
    }

    /**
     * @api {get} /common/hospitalList 获取附近的医院
     * @apiGroup 常用接口
     * @apiVersion 0.1.0
     * @apiDescription 获取附近支持租赁的医院列表
     * @apiSuccess {Object} Object 开通的城市列表
     * @apiSuccessExample {json} Success-Response:
          {"code":0,"msg":"", "data":{ "list": {}, "total":11,"page":1,"limit":30,"pages":1 }}
     */
    @RequestMapping("/hospitalList")
    public BaseResult getNearbyHospital(){
       //TODO
       return RespUtil.success();
    }

    /**
     * @api {get} /common/shareApp 分享应用
     * @apiGroup 常用接口
     * @apiVersion 0.1.0
     * @apiDescription 获取分享应用的信息
     * @apiSuccess {Object} Object
     * @apiSuccessExample {json} Success-Response:
                     { "msg": "成功", "code":0, "data": {} }
     */
    @RequestMapping("/shareApp")
    public BaseResult shareApp() {
        //TODO
        return RespUtil.success();
    }

    /**
     * @api {get} /common/locationCity 定位城市
     * @apiParam {number} lat 纬度，必填
     * @apiParam {number} lng 经度，必填
     * @apiParam {String} radius 半径，单位米(默认:1000)
     * @apiParam {String} poitype POI类型列表（默认：地名地址信息）
     * @apiParam {String} output 返回数据类型(默认:json)
     * @apiGroup 常用接口
     * @apiVersion 0.1.0
     * @apiDescription 定位用户当前所在城市
     * @apiSuccess {int} code 请求状态码，0表示成功,其它参考状态码文档
     * @apiSuccess {String} message 结果消息说明
     * @apiSuccess {boolean} success 请求是否成功
     * @apiSuccess {Object} data 请求响应的数据
     * @apiSuccessExample {json} Success-Response:
     * {
     *     "location": "高德返回的数据",
     *     "code": "请求状态码，0表示成功，其它参考状态码文档",
     *     "success": "请求是否成功",
     *     "timestamp": "服务器当前时间戳10位精确到秒",
     *     "message": "请求成功/失败说明",
     *     "data": {
     *         "isOpen": "经纬度对应的城市是否已开通服务",
     *         "location": "高德地图WEBAPI返回的JSON字符串"
     *     }
     * }
     */
    @RequestMapping("/locationCity")
    public BaseResult getCityByLngLat(String lng, String lat,String radius,String poitype,String output) throws UnsupportedEncodingException {
      if(StringUtils.isBlank(lng) || StringUtils.isBlank(lat)) {
          return RespUtil.fail();
      }
      String url = UrlConfig.GET_CITY_URL_BY_LNG_LAT.replaceAll("LNG",lng);
      url = url.replaceAll("LAT",lat);
      if(StringUtils.isNotBlank(radius)) {
          url += "&radius="+ URLEncoder.encode(radius,"utf-8");
      }
      if(StringUtils.isNotBlank(poitype)) {
          url += "&poitype="+ URLEncoder.encode(poitype,"utf-8");
      }
      if(StringUtils.isNotBlank(output)) {
          url += "&output=" + URLEncoder.encode(output,"utf-8");
      }

      String locationRst = HttpUtil.sendGet(url);
      logger.debug("获取经纬度对应城市 {},{},{}",lat,lng,locationRst);
      Map<String,Object> result = new HashMap<>();
      result.put("location",locationRst);
      //{"status":"1","regeocode":{"addressComponent":{"city":[],"province":"北京市","adcode":"110108","district":"海淀区","towncode":"110108012000","streetNumber":{"number":"17号","location":"116.298266,39.95994","direction":"北","distance":"69.6193","street":"长春桥路"},"country":"中国","township":"海淀街道","businessAreas":[{"location":"116.298072,39.967157","name":"万柳","id":"110108"},{"location":"116.284753,39.959935","name":"世纪城","id":"110108"},{"location":"116.303364,39.97641","name":"万泉河","id":"110108"}],"building":{"name":[],"type":[]},"neighborhood":{"name":[],"type":[]},"citycode":"010"},"formatted_address":"北京市海淀区海淀街道长春桥路"},"info":"OK","infocode":"10000"}
      Map<String,Object> locationMap = JacksonUtil.gson.fromJson(locationRst,Map.class);
      Object regeocode = locationMap.get("regeocode");
      if(regeocode != null) {
          Map<String,Object> addressMap = (Map<String, Object>) regeocode;
          Map<String,Object> addressComponentMap = (Map<String, Object>) addressMap.get("addressComponent");
          String city = addressComponentMap.get("city").toString();
          logger.debug("city---->{}",city);
          if(StringUtils.isBlank(city) || "[]".equals(city)) {
              city = addressComponentMap.get("province").toString();
          }
          int isOpen = ejiaOpenCityService.isOpen(city);
          result.put("isOpen",isOpen);
      }
      return RespUtil.success(result);
    }


    /**
     * @api {get} /common/locationSearch 地址搜索
     * @apiParam {boolean} citylimit 是否值搜索指定城市地质(默认:true)
     * @apiParam {number} children 是否将搜索结果子数据合并
     * @apiParam {number} offset 每页返回数据条数(默认:10)
     * @apiParam {String} city 城市名(例如:北京市)
     * @apiParam {String} keywords 搜索的关键字
     * @apiGroup 常用接口
     * @apiVersion 0.1.0
     * @apiDescription 进行地址的搜索
     * @apiSuccess {int} code 请求状态码，0表示成功,其它参考状态码文档
     * @apiSuccess {String} message 结果消息说明
     * @apiSuccess {boolean} success 请求是否成功
     * @apiSuccess {Object} data 请求响应的数据
     * @apiSuccessExample {json} Success-Response:
     * {
     * "code": "请求状态码，0表示成功，其它参考状态码文档",
     * "success": "请求是否成功",
     * "timestamp": "服务器当前时间戳10位精确到秒",
     * "message": "请求成功/失败说明",
     * "data": "请求响应数据，对象或数组"
     * }
     */
    @RequestMapping("/locationSearch")
    public BaseResult searchLocation(@RequestParam(defaultValue = "true")String citylimit,
                                      @RequestParam(defaultValue = "1")String children,
                                      @RequestParam(defaultValue = "10")String offset,
                                     String city,
                                     String keywords) throws UnsupportedEncodingException {
        if(StringUtils.isBlank(keywords)) {
            return RespUtil.fail();
        }
        String url = SEARCH_AROUND_LOCATION_URL + "&keywords="+ URLEncoder.encode(keywords,"utf-8");
        if(StringUtils.isNotBlank(citylimit)) {
            url+= "&citylimit="+ URLEncoder.encode(citylimit,"utf-8");
        }
        if(StringUtils.isNotBlank(city)) {
            url += "&city="+ URLEncoder.encode(city,"utf-8");
        }
        if(StringUtils.isNotBlank(children)) {
            url += "&children=" + URLEncoder.encode(children,"utf-8");
        }
        if(StringUtils.isNotBlank(offset)) {
            url += "&offset=" + URLEncoder.encode(offset,"utf-8");
        }

        String locationRst = HttpUtil.sendGet(url);
        Map<String,Object> result = new HashMap<>();
        result.put("location",locationRst);
        return RespUtil.success(result);
    }

    @RequestMapping("/uploadFile")
    public BaseResult uploadFile(@RequestParam(name = "files") MultipartFile[] files){
        List<String> result = new ArrayList<>();
        for (MultipartFile file : files) {
            if (file.isEmpty()) {
                continue;
            }
            String fileName = file.getOriginalFilename();  // 文件名
            String suffixName = fileName.substring(fileName.lastIndexOf("."));  // 后缀名
            String filePath = FILEPATH; // 上传后的路径
//            if (System.getProperty("os.name").toLowerCase().contains("win")) {
//                filePath = "D:\\imgs\\";
//            }
            fileName = UUID.randomUUID() + suffixName; // 新文件名
            File dest = new File(filePath + fileName);
            if (!dest.getParentFile().exists()) {
                dest.getParentFile().mkdirs();
            }
            try {
                file.transferTo(dest);
                String filename = FILEURL + fileName;
                result.add(filename);
            } catch (IOException e) {
                e.printStackTrace();
                throw new BizException("上传失败");
            }
        }
        return RespUtil.success(result);
    }

    @RequestMapping("/getHourReachHospitalList")
    public BaseResult getHourReachHospitalList(@LoginUser Integer userId, @RequestBody HourReachHospitalForm hourReachHospitalForm) {
        List<String> cityList = hourReachHospitalForm.getCityList();
        if (null != hourReachHospitalForm.getIsUser() && 1 == hourReachHospitalForm.getIsUser()) {
            if (userId == null) {
                return RespUtil.unlogin();
            }
            List<LitemallAddress> addresses = addressService.queryByUid(userId);
            List<String> citys = addresses.stream().map(p -> p.getCity()).collect(Collectors.toList());
            cityList.addAll(citys);
        }

        List<AgedmallHospitalSend> hospitalSends = agedmallHospitalSendService.getByCitys(cityList);
        List<HourReachHospitalVo> hospitalVos = hospitalSends.stream().map(HourReachHospitalVo::getInstance).collect(Collectors.toList());

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("list", hospitalVos);
        return RespUtil.success(jsonObject);
    }




    /**
     * 上传文件
     */
    @RequestMapping("/uploadImage")
    public Object uploadFile(@RequestParam("file") MultipartFile file) {
        return uploadService.uploadFile(file);
    }
}
